package naga.x.util;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Scheduler {

	protected static final Logger LOG = LoggerFactory.getLogger(Scheduler.class);
	
	protected ScheduledExecutorService service;
	
	protected static class ScheduleTask implements Runnable {
		private Runnable task;
		protected ScheduleTask(Runnable task) {
			this.task = task;
		}
		@Override
		public void run() {
			try {
				task.run();
			} catch (Exception e) {
				LOG.error("[SCHEDULE TASK RUN ERROR]" + (task != null ? task.getClass() : "TASK NULL"), e);
			}
		}
	}
	
	public Scheduler() {
		this(Executors.newScheduledThreadPool(2, new ThreadFactory() {
			@Override
			public Thread newThread(Runnable r) {
				Thread t = new Thread(r, "App-Schedule");
				t.setDaemon(true);
				return t;
			}
		}));
	}
	
	public Scheduler(ScheduledExecutorService service) {
		this.service = service;
	}
	
	public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
		return service.schedule(new ScheduleTask(command), delay, unit);
	}
	
	public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
            long initialDelay,
            long period,
            TimeUnit unit) {
		return service.scheduleAtFixedRate(new ScheduleTask(command), initialDelay, period, unit);
	}
	
	public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
            long initialDelay,
            long delay,
            TimeUnit unit) {
		return service.scheduleWithFixedDelay(new ScheduleTask(command), initialDelay, delay, unit);
	}

	public boolean isShutdown() {
		return service.isShutdown();
	}

	public void shutdown() {
		service.shutdown();
	}
	
}
